package com.chalmers.foa.gamemodel.gameobjects;

import android.graphics.Point;

public abstract class GameObjectAdapter implements IGameObject{

	protected int width, height;
	
	private Point position;
	private Point oldPosition;
	private Point startPosition;
	private boolean alive;
	private int layer;
	private int id;
	
	private boolean solid;
	private boolean affectedByGravity;
	private boolean affectedByTilting;
	private boolean hazardous;
	private boolean isBound,hasBound;
	private int boundID;
	
	private IGameObject boundObject;
	private IGameObject hostObject;
	
	public GameObjectAdapter(Point position,int _layer,int _boundID, boolean solid,
			boolean affectedByGravity, boolean affectedByTilting, boolean hazardous){
		this.solid = solid;
		this.affectedByGravity = affectedByGravity;
		this.affectedByTilting = affectedByTilting;
		this.hazardous = hazardous;
		alive = true;
		layer=_layer;
		boundID=_boundID;
		isBound=false;
		hasBound=false;
		startPosition= new Point();
		oldPosition = new Point();
		hostObject=null;
		boundObject=null;
		this.position = new Point();
		setInitialPosition(position);
	}
	public GameObjectAdapter(Point _position){
		this(_position,0,-1, false, false, false, false);
	}

	public int getBoundID(){
		return boundID;
	}
	public void bindObject(IGameObject _boundObject, Point offset){// TODO Point offset
		if(!_boundObject.isBound()){
			boundObject = _boundObject;
			boundObject.setBound(true);
			boundObject.setHost(this);
			hasBound=true;
			if(offset!=null)
				boundObject.setNewPosition(new Point(getPosition().x+offset.x,getPosition().y+offset.y));
		}
		else{
			unbindObject(_boundObject);
			bindObject(_boundObject,offset);
		}
	}
	public void unbindObject(){
		unbindObject(boundObject);
		boundObject= null;
	}
	public void unbindObject(IGameObject _boundObject){
		if(_boundObject!=null){
			_boundObject.setBound(false);
			_boundObject.getHost().unsetBoundObject();
			_boundObject = null;
		}
		hasBound=false;
	}
	public boolean hasBound(){
		return hasBound;
	}
	public IGameObject getBoundObject(){
		return boundObject;
	}
	public void setNewPosition(Point position){
		oldPosition.set(position.x, position.y);
		this.position.set(position.x, position.y);
	}
	
	public void setPosition(Point position){
		setInitialPosition(position);
	}

	public int getHeight() {
		return height;
	}

	public Point getPosition() {
		return position;
	}

	public int getWidth() {
		return width;
	}
	
	public boolean isAlive() {
		return alive;
	}
	
	public void setAlive(boolean _alive) {
		alive = _alive;
	}

	public Point getPreviousPosition() {
		return oldPosition;
	}

	public void translate(int x, int y) {
		oldPosition.set(position.x, position.y);
		position.x += x;
		position.y += y;
		if(boundObject!=null)
			boundObject.translate(x, y);
	}
	
	public void translate(Point offset) {
		translate(offset.x, offset.y);
	}
	
	public void revertToStartPosition() {
		setPosition(startPosition);
	}

	private void setInitialPosition(Point position) {
		oldPosition.x = position.x;
		oldPosition.y = position.y;
		
		startPosition.x = position.x;
		startPosition.y = position.y;
		
		this.position.x = position.x;
		this.position.y = position.y;
	}
	
	public boolean isSolid() {
		return solid;
	}
	
	public boolean affectedByGravity() {
		return affectedByGravity;
	}
	
	public boolean affectedByTilting() {
		return affectedByTilting;
	}
	
	public boolean isHazardous() {
		return hazardous;
	}
	
	public int getLayer(){
		return layer;
	}
	
	public void update() {}
	
	public void setID(int _id){
		id=_id;
	}
	public int getID(){
		return id;
	}
	public boolean isBound(){
		return isBound;
	}
	public void setBound(boolean value){
		isBound=value;
	}
	public IGameObject getHost(){
		return hostObject;
	}
	public void unsetBoundObject(){
		boundObject=null;
	}
	public void setHost(IGameObject _host){
		hostObject = _host;
	}
	@Override
	public int compareTo(IGameObject obj) {
		if(getLayer()>obj.getLayer())
			return -1;
		else if(getLayer()<obj.getLayer())
			return 1;
		return 0;
	}
}
